/*
 * Copyright (c) Huawei Technologies Co.,Ltd. 2023. All rights reserved.
 */
package mybatis;

import org.opengauss.Logger;
import org.opengauss.driver.DriverInfoManager;
import org.opengauss.driver.IDriverInfo;
import org.opengauss.mapper.DateTimestampMapper;
import org.opengauss.service.FactoryInstance;
import org.opengauss.vo.DateTimestampVo;
import common.testcase.BaseMyBatisTestCase;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Title: the DateTimestampMybatisProviderTest class.
 * <p>
 * Description:
 *
 * @author justbk
 * @version [Tools 0.0.1, 2023/8/18]
 * @since 2023/8/18
 */
public class DateTimestampMybatisProviderTest extends BaseMyBatisTestCase<DateTimestampMapper> {
    private static String INFO_KEY = "db2";
    DateFormat FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    
    @Before
    public void setUp() {
        initSession();
        mapper.dropTable();
        mapper.createTable();
        initAutoId(mapper);
    }
    
    @After
    public void tearDown() {
//        mapper.dropTable();
    }
    
    public static Date convertDate(Date date) {
        return convertDate(date, false);
    }
    
    public static Date convertDate(Date date, boolean zero) {
        long d1long = date.getTime();
        if (d1long/(100)%10 >= 5) {
            d1long += 1 * 1000;
        }
        if (zero) {
            d1long -= (d1long%1000);
        }
        return new Date(d1long);
    }
    
    @Test
    public void test() throws SQLException, ParseException, InterruptedException {
        int size = 10;
        List<DateTimestampVo> srcDate = new ArrayList<>(size);
        Date init1 = new Date();
    
        for (int i = 0; i < size; i++) {
            init1 = new Date(init1.getTime() + 1000);
            DateTimestampVo vo = new DateTimestampVo(getNextId(), init1, new Date(init1.getTime() + 1000));
            srcDate.add(vo);
            mapper.insert(vo);
        }
        List<DateTimestampVo> results = mapper.selectAll();
        Assert.assertEquals(size, results.size());
        
        DateTimestampVo vo1 = new DateTimestampVo(getNextId(), new Date(2023 - 1900, 0, 1), new Date(2023 - 1900, 11, 31));
        srcDate.add(vo1);
        mapper.insert(vo1);
    
        for (DateTimestampVo vo: srcDate) {
            Date newD1Vo = FORMAT.parse(FORMAT.format(convertDate(vo.getD1())));
            DateTimestampVo newVo = new DateTimestampVo(0, newD1Vo, null);
            List<DateTimestampVo> query1 = mapper.selectByVo(newVo);
            Assert.assertEquals(vo.toString(), 1, query1.size());
            
            DateTimestampVo newVo2 = new DateTimestampVo(0, newD1Vo, vo.getD2());
            List<DateTimestampVo> query2 = mapper.selectByVo(newVo2);
            Assert.assertEquals(1, query2.size());
        }
    }
    
    @Test
    public void test1() throws SQLException {
        DateTimestampVo vo = new DateTimestampVo(getNextId(), new Date(), new Date());
        mapper.insert(vo);
        String sql = "select * from t_date_timestamp where d1=?";
        try (Connection conn = sqlSession.getConnection()) {
            try (PreparedStatement ps = conn.prepareStatement(sql)) {
                ps.setTimestamp(1, new Timestamp(convertDate(vo.getD1(), true).getTime()));
                try (ResultSet rs = ps.executeQuery()) {
                    int number = 0;
                    while (rs.next()) {
                        number ++;
                    }
                    if (number == 0) {
                        Assert.fail("can't find any");
                    }
                    Logger.info("get number:" + number);
                }
            }
        }
    }
    
    @Test
    public void test2() throws SQLException {
        DateTimestampVo vo = new DateTimestampVo(getNextId(), new Date(2023, 1, 2), new Date(2023, 2, 1));
        mapper.insert(vo);
        String sql = "select * from t_date_timestamp where d2=?";
        try (Connection conn = sqlSession.getConnection()) {
            try (PreparedStatement ps = conn.prepareStatement(sql)) {
                ps.setTimestamp(1, new Timestamp(vo.getD2().getTime()));
                try (ResultSet rs = ps.executeQuery()) {
                    int number = 0;
                    while (rs.next()) {
                        number ++;
                    }
                    if (number == 0) {
                        Assert.fail("can't find any");
                    }
                    Logger.info("get number:" + number);
                }
            }
        }
    }
    
    @Test
    public void test4() throws SQLException, ParseException {
        DateTimestampVo vo = new DateTimestampVo(getNextId(), new Date(2023 - 1900, 0, 1, 0,0 ,0),
                new Date(2023 - 1900, 2, 1, 0, 0, 0));
        Date new1 = FORMAT.parse("2023-05-01 05:02:03");
        vo.setD1(new1);
        mapper.insert(vo);
        String sql = "select * from t_date_timestamp where d1=?";
        try (Connection conn = sqlSession.getConnection()) {
            try (PreparedStatement ps = conn.prepareStatement(sql)) {
                ps.setTimestamp(1, new Timestamp(vo.getD1().getTime()));
                try (ResultSet rs = ps.executeQuery()) {
                    int number = 0;
                    while (rs.next()) {
                        number ++;
                    }
                    if (number == 0) {
                        Assert.fail("can't find any");
                    }
                    Logger.info("get number:" + number);
                }
            }
        }
    }
    
    @Test
    public void test5() throws SQLException, ParseException {
        DateTimestampVo vo = new DateTimestampVo(getNextId(), new Date(2023 - 1900, 0, 1, 0,0 ,0),
                new Date(2023 - 1900, 2, 1, 0, 0, 0));
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date new1 = format.parse("2023-05-01 05:02:03");
        vo.setD1(new1);
        mapper.insert(vo);
        DateTimestampVo newVo = new DateTimestampVo(0, new1, null);
        List<DateTimestampVo> query = mapper.selectByVo(newVo);
        Assert.assertEquals(1, query.size());
    }
    
    @Override
    protected void initSession() {
        IDriverInfo info = DriverInfoManager.getInfo(INFO_KEY);
        try {
            SqlSessionFactory factory = FactoryInstance.INSTANCE.getSqlSessionFactory(info);
            sqlSession = factory.openSession(true);
            mapper = sqlSession.getMapper(DateTimestampMapper.class);
        } catch (IOException sqlExp) {
            sqlExp.printStackTrace();
        }
    }
    
    @Override
    public int getMaxId(final DateTimestampMapper mapper) {
        return mapper.selectMaxId();
    }
}
